package com.sf.tools.generate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sf.tools.common.CheckI18NProgressHandler;
import com.sf.tools.common.Common;
import com.sf.tools.common.PieChartUtil;

public class CodeCount {

	public static String LOG_MARK = "CODE_COUNT";
	
	private CheckI18NProgressHandler progressHandler;
	private static long normalLines;	//代码
	private static long commentLines;	//注释
	private static long whiteLines;		//空行
	private List<String> suffixs;		//要统计的文件的后缀名
	
	private void print(String content){
		System.out.println(LOG_MARK+content);
	}
	
	public CodeCount(){
		normalLines = 0;
		commentLines = 0;
		whiteLines = 0;
		suffixs = new ArrayList<String>();
	}
	
	public String start(String path, String suffix) {
		Common.files.clear();
		suffix = suffix.replace("，", ",");
		String[] splits = suffix.split(",");
		
		suffixs = Arrays.asList(splits);
		
		List<File> list = Common.findFilesByFileName(path, suffixs, true);
//		for (File file : list) {
//			System.out.println(file.getPath());
//		}
//		print("count: "+list.size());
		this.progressHandler.loadTaskCount(list.size()==0?1:list.size(),null);
		
		try {
			count(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		print("***************************************************");
		print("统计完毕!");
		long totalCount = normalLines+commentLines+whiteLines;
		print("总行数：" + totalCount);
		PieChartUtil pc = new PieChartUtil();
		if(totalCount != 0){
			print("代码：" + normalLines + " 比重：" + Double.valueOf(new DecimalFormat("##.00").format(Double.valueOf(normalLines)/totalCount*100))+"%");
			print("注释：" + commentLines + " 比重：" + Double.valueOf(new DecimalFormat("##.00").format(Double.valueOf(commentLines)/totalCount*100))+"%");
			print("空行：" + whiteLines + " 比重：" + Double.valueOf(new DecimalFormat("##.00").format(Double.valueOf(whiteLines)/totalCount*100))+"%");
			print("***************************************************");
		}
		Map<String,Double> data = new HashMap<String,Double>();
		data.put("count", Double.valueOf(totalCount));
		data.put("代码", Double.valueOf(normalLines));
		data.put("注释", Double.valueOf(commentLines));
		data.put("空行", Double.valueOf(whiteLines));
		pc.setData(data);
		return pc.drawPic();
		
//		Common.write(file, buff.toString());
//		print("检测完毕!");
//		print("检查结果生成文件:"+file.getPath());
	}
//
	
	public void count(String path) throws Exception{
		File ff = new File(path);
		if(!ff.exists()) return ;
		if(ff.isDirectory()){
			File[] files = ff.listFiles();
			for (File file : files) {
				//过滤 .svn 文件
				if(file.getName().toLowerCase().endsWith(".svn")) continue;
				
				if(file.isFile() && Common.endWithSuffixs(file.getName(), suffixs)){
					parse(file);
				}else if(file.isDirectory()){
					count(file.getPath());
				}
			}
		}else if(ff.isFile() && Common.endWithSuffixs(ff.getName(), suffixs)){
			parse(ff);
		}
	}
	private void parse(File file) {
		this.progressHandler.doneTaskCount();
		print("正在统计:" + file.getPath());
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
			String filename = file.getName().toLowerCase();
			if(filename.endsWith(".java") || filename.endsWith(".js")){
				countJAVA(br);
			}else if(filename.endsWith(".html") || filename.endsWith(".htm")){
				countHTML(br);
			}else if(filename.endsWith(".jsp")){
				countJSP(br);
			}else if(filename.endsWith(".properties")){
				countPROPERTIES(br);
			}else if(filename.endsWith(".xml")){
				countXML(br);
			}else{
				countOTHER(br);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
	}
	
	public void countJAVA(BufferedReader br){
		boolean comment = false;
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else if ((line.startsWith("/*") && !line.endsWith("*/"))) {
					commentLines ++;
					comment = true;	
				} else if ((line.startsWith("/*") && line.endsWith("*/"))) {
					commentLines ++;
				} else if (true == comment) {
					commentLines ++;
					if(line.endsWith("*/")) {
						comment = false;
					}
				} else if (line.startsWith("//")) {
					commentLines ++;
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void countHTML(BufferedReader br){
		boolean comment = false;
		boolean isScript = false;
		boolean scriptComment = false;
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else if ((line.startsWith("<!--") && !line.endsWith("-->"))) {
					commentLines ++;
					comment = true;	
				} else if ((line.startsWith("<!--") && line.endsWith("-->"))) {
					commentLines ++;
				} else if (true == comment) {
					commentLines ++;
					if(line.endsWith("-->")) {
						comment = false;
					}
				} else if(line.startsWith("<script") && !line.endsWith("</script>")){
					isScript = true;
					normalLines ++;
				} else if(line.endsWith("</script>")){
					isScript = false;
					normalLines ++;
				} else if(true == isScript){//html 中 javascript 代码的统计
					if(line.matches("^[\\s&&[^\\n]]*$")) {
						whiteLines ++;
					} else if ((line.startsWith("/*") && !line.endsWith("*/"))) {
						commentLines ++;
						scriptComment = true;	
					} else if ((line.startsWith("/*") && line.endsWith("*/"))) {
						commentLines ++;
					} else if (true == scriptComment) {
						commentLines ++;
						if(line.endsWith("*/")) {
							scriptComment = false;
						}
					} else if (line.startsWith("//")) {
						commentLines ++;
					} else {
						normalLines ++;
					}
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void countJSP(BufferedReader br){
		boolean comment = false;
		boolean isScript = false;
		boolean scriptComment = false;
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else if ((line.startsWith("<!--") && !line.endsWith("-->")) ||
						   (line.startsWith("<%--") && !line.endsWith("--%>"))) {
					commentLines ++;
					comment = true;	
				} else if ((line.startsWith("<!--") && line.endsWith("-->")) ||
						   (line.startsWith("<%--") && line.endsWith("--%>"))) {
					commentLines ++;
				} else if (true == comment) {
					commentLines ++;
					if(line.endsWith("-->") || line.endsWith("--%>")) {
						comment = false;
					}
				} else if(line.startsWith("<script") && !line.endsWith("</script>") || 
						 (line.startsWith("<%") && !line.endsWith("%>"))){
					isScript = true;
					normalLines ++;
				} else if(line.endsWith("</script>") || line.endsWith("%>")){
					isScript = false;
					normalLines ++;
				} else if(true == isScript){//html 中 javascript 代码的统计
					if(line.matches("^[\\s&&[^\\n]]*$")) {
						whiteLines ++;
					} else if ((line.startsWith("/*") && !line.endsWith("*/"))) {
						commentLines ++;
						scriptComment = true;	
					} else if ((line.startsWith("/*") && line.endsWith("*/"))) {
						commentLines ++;
					} else if (true == scriptComment) {
						commentLines ++;
						if(line.endsWith("*/")) {
							scriptComment = false;
						}
					} else if (line.startsWith("//")) {
						commentLines ++;
					} else {
						normalLines ++;
					}
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void countPROPERTIES(BufferedReader br){
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else if (line.startsWith("#")) {
					commentLines ++;
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void countXML(BufferedReader br){
		boolean comment = false;
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else if ((line.startsWith("<!--") && !line.endsWith("-->"))) {
					commentLines ++;
					comment = true;	
				} else if ((line.startsWith("<!--") && line.endsWith("-->"))) {
					commentLines ++;
				} else if (true == comment) {
					commentLines ++;
					if(line.endsWith("-->")) {
						comment = false;
					}
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void countOTHER(BufferedReader br){
		String line = "";
		try {
			while((line = br.readLine()) != null) {
				line = line.trim().replace("﻿", "");
				if(line.matches("^[\\s&&[^\\n]]*$")) {
					whiteLines ++;
				} else {
					normalLines ++;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
//		List<String> suffix = new ArrayList<String>(){{
//			add(".java");
//			add(".js");
//		}};
//		System.out.println(endWithSuffixs("aaa.java",suffix));
//		String path = "D:\\project\\vms\\V2.3\\code\\module\\vmsreport";
//		try {
//			new CodeCount().start(path);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		Double d1 = Double.valueOf(new DecimalFormat("####.00").format(120d/1431*100));
//		System.out.println(d1+"%");
//		System.out.println(120d/1431*100);
		
//		System.out.println("normalLines:" + normalLines);
//		System.out.println("commentLines:" + commentLines);
//		System.out.println("whiteLines:" + whiteLines);
//		System.out.println("############驾驶员分布统计 ##############################".matches("^#.*"));
//		System.out.println("############驾驶员分布统计 ##############################".startsWith("#"));
//		System.out.println("﻿############驾驶员分布统计 ##############################".startsWith("﻿"));
//		System.out.println(("﻿1###########驾驶员分布统计 ##############################".substring(0,2)));
	}

	public CheckI18NProgressHandler getProgressHandler() {
		return progressHandler;
	}

	public void setProgressHandler(CheckI18NProgressHandler progressHandler) {
		this.progressHandler = progressHandler;
	}

}
